#!/usr/bin/env python3
"""Check if any function nodes within OrderTemplate.java invoke sendEmail"""

import pickle
import networkx as nx
from neo4j import GraphDatabase

# Load the original graph
print("Loading original graph...")
with open('business-payout.pkl', 'rb') as f:
    G = pickle.load(f)

file_node = 'business-payout-biz/src/main/java/com/pingpongx/business/payout/biz/service/core/OrderTemplate.java'
target_function = 'sendEmail'

print(f"\n=== Checking for '{target_function}' invocations in NetworkX Graph ===")
print(f"File: {file_node}")

if file_node in G:
    # Get all functions in this file
    all_functions = []

    # First get the class
    for source, target, data in G.out_edges(file_node, data=True):
        if data.get('type') == 'contains':
            class_node = target
            # Get functions from the class
            for s, t, d in G.out_edges(class_node, data=True):
                if d.get('type') == 'contains' and G.nodes[t].get('type') == 'function':
                    all_functions.append(t)

    print(f"Total functions in file: {len(all_functions)}")

    # Check invocations containing sendEmail
    found_invocations = []
    for func in all_functions:
        if func in G:
            for source, target, data in G.out_edges(func, data=True):
                if data.get('type') == 'invokes':
                    if target_function.lower() in target.lower():
                        found_invocations.append((func, target))

    if found_invocations:
        print(f"\n✅ Found {len(found_invocations)} invocations containing '{target_function}':")
        for invoker, invoked in found_invocations:
            func_name = invoker.split('.')[-1]
            print(f"  {func_name} -> {invoked}")
    else:
        print(f"\n❌ No invocations containing '{target_function}' found")

print(f"\n=== Checking in Neo4j Database ===")

driver = GraphDatabase.driver("bolt://localhost:5018", auth=("neo4j", "neo4j123"))

with driver.session() as session:
    # Check for sendEmail invocations (case insensitive)
    result = session.run("""
        MATCH (file:Node {id: $file_id})-[:CONTAINS*]->(func:Node {type: 'function'})
        MATCH (func)-[:INVOKES]->(target:Node)
        WHERE toLower(target.id) CONTAINS toLower($function_name)
        RETURN func.id as invoker, target.id as invoked
        ORDER BY func.id
    """, file_id=file_node, function_name=target_function)

    invocations = list(result)
    if invocations:
        print(f"\n✅ Found {len(invocations)} invocations containing '{target_function}':")
        for inv in invocations:
            func_name = inv['invoker'].split('.')[-1]
            print(f"  {func_name} -> {inv['invoked']}")
    else:
        print(f"\n❌ No functions in this file invoke anything containing '{target_function}'")

    # Search for any sendEmail nodes in the entire graph
    result = session.run("""
        MATCH (n:Node)
        WHERE toLower(n.id) CONTAINS 'sendemail'
        RETURN n.id, n.type
        LIMIT 20
    """)

    email_nodes = list(result)
    if email_nodes:
        print(f"\n📧 Found {len(email_nodes)} nodes containing 'sendEmail' in the graph:")
        for node in email_nodes[:10]:
            print(f"  - {node['n.id']} (type: {node['n.type']})")

    # Check who invokes these sendEmail functions
    result = session.run("""
        MATCH (invoker:Node)-[:INVOKES]->(target:Node)
        WHERE toLower(target.id) CONTAINS 'sendemail'
        RETURN invoker.id as invoker, target.id as target
        LIMIT 20
    """)

    global_invocations = list(result)
    if global_invocations:
        print(f"\n📍 Global invocations of sendEmail functions:")
        for inv in global_invocations[:10]:
            print(f"  {inv['invoker']}")
            print(f"    -> {inv['target']}")

    # Check for email/mail related invocations from OrderTemplate
    result = session.run("""
        MATCH (file:Node {id: $file_id})-[:CONTAINS*]->(func:Node {type: 'function'})
        MATCH (func)-[:INVOKES]->(target:Node)
        WHERE toLower(target.id) CONTAINS 'mail' OR toLower(target.id) CONTAINS 'email'
        RETURN func.id as invoker, target.id as invoked
        ORDER BY func.id
    """, file_id=file_node)

    mail_invocations = list(result)
    if mail_invocations:
        print(f"\n📮 Email/Mail related invocations from OrderTemplate functions:")
        for inv in mail_invocations:
            func_name = inv['invoker'].split('.')[-1]
            target_name = inv['invoked'].split('.')[-1] if '.' in inv['invoked'] else inv['invoked']
            print(f"  {func_name} -> {target_name}")

driver.close()

print("\n=== Summary ===")
print(f"Searched for '{target_function}' invocations in OrderTemplate.java")
print("Also searched for any email/mail related function calls.")